#include <stdio.h>
#include <iostream>
#include "AuditPlanFun.h"
#include <string>
#include <time.h>
#include <sys/types.h>
//#include <ifaddrs.h>
//#include <netinet/in.h>
#include <string.h>
//#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//#include <net/if.h>
//#include <arpa/inet.h>
//#include <sys/ioctl.h>
//#include <sys/socket.h>
#include <error.h>
//#include "GenKey/SqlUtil.h"
#include "sqlite3.h"
#include "UsbIO.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <dirent.h>
//#include <curl.h>
//#include "Core/CoreBase.h"
#include <unistd.h>
#include <sys/types.h>
#include <QNetworkInterface>
#include <QList>
//#include <pwd.h>
const char *username = std::getenv("USER");
std::string usbPath;

// #include "MyDB.h"
using namespace std;
using namespace UsbEncrypt;


//windows
AuditFun::AuditFun(QString drivePath){
    usbPath = drivePath.toStdString();
    std::cout << "--windows--------the usb path is--------" << std::endl
              << usbPath << std::endl;

}

//linux
AuditFun::AuditFun(){
    DIR *dir;
    struct dirent *entry;
    // std::string usbPath;

    // dir = opendir("/media/内容/" + std::string(username)).c_str());
    dir = opendir("F:/");
    if (dir == nullptr)
    {
        std::cout << "can not open directorty" << std::endl;
    }

    //uid_t uid = getuid();  // 获取当前进程的有效用户 ID

    // struct passwd* pw = getpwuid(uid);
    // std::string Username = pw->pw_name;
    //     std::cout << "当前非 root 用户名：" << Username << std::endl;

    while ((entry = readdir(dir)) != nullptr)
    {
        //if (entry->d_type == DT_DIR && std::string(entry->d_name) != "." && std::string(entry->d_name) != "..")

        if (std::string(entry->d_name) != "." && std::string(entry->d_name) != "..")
        {

            // usbPath = "/media/" + std::string(username) + "/" + std::string(entry->d_name);
            std::string usbname = std::string(entry->d_name);
            std::cout << "------------usbname is--------" << std::endl
                      << usbname << std::endl;

            //std::string Username = std::string(username);
            //std::cout << "------------Username is--------" << std::endl
            //          << Username << std::endl;
                      
            // if (usbname != Username && usbname != "root" && usbname != "user" )
            // if (usbname != "root" && usbname != "user" )
            // {
            //     /* code */
            //     usbPath = "F:/" + usbname;
            //     std::cout << "------------the usb path is--------" << std::endl
            //               << usbPath << std::endl;
            //     break;
            // }

                usbPath = "F:" ;
                std::cout << "------------the usb path is--------" << std::endl
                          << usbPath << std::endl;
                break;
        }
    }
    // sleep(2);
    // string str(path.begin(), path.end());
    // usbPath = str;
    // std::cout << "------------usb的路径是--------" << std::endl
    //           << usbPath << std::endl;

    closedir(dir);
    if (usbPath.empty())
    {
        std::cout << "unable to find the u disk\n";
    }

}

// sqlite回调函数
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
    int i;
    for (i = 0; i < argc; i++)
    {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

// sqlite初始化文件移动函数
void AuditFun::MoveFilesToUSB(const std::vector<std::string> &filePaths, const std::string &usbPath)
{
    for (const auto &filePath : filePaths)
    {
        std::string fullPath;
        const char *pwdpath = __FILE__;
        std::string Pwdpath = pwdpath;
        //size_t lastSeparatorPos = Pwdpath.find_last_of('/');
	  std::string directoryPath = "home/ubuntu/Downloads/usbencrypt1123zhuceji1129/usbencrypt1123zhuceji/src/Main";
        //if (lastSeparatorPos != std::string::npos)
        //{
            //std::string directoryPath = Pwdpath.substr(0, lastSeparatorPos);
            // 拼接文件路径
            //fullPath = directoryPath + "/" + filePath;
        //}
        fullPath = directoryPath + "/" + filePath;
        std::ifstream sourceFile(fullPath, std::ios::binary);
        if (!sourceFile)
        {
            std::cout << "无法打开源文件" << fullPath << std::endl;
            continue;
        }
        size_t lastSlashIndex = fullPath.find_last_of("/\\");
        std::string filename = fullPath.substr(lastSlashIndex + 1);
        std::string destinationPath = usbPath + "/" + filename;
        std::cout << destinationPath << "------------------" << std::endl;
        std::ofstream destinationFile(destinationPath, std::ios::binary);

        if (!destinationFile)
        {
            std::cout << "无法打开目的文件" << usbPath << std::endl;
            continue;
        }

        destinationFile << sourceFile.rdbuf();
        std::cout << "成功移动文件: " << fullPath << " 到: " << usbPath << std::endl;
    }
    std::cout << "所有文件成功移动到U盘中\n";
}

// sqlite初始化函数
bool AuditFun::InitializeSQL()
{

    // DIR *dir;
    // struct dirent *entry;
    // // std::string usbPath;

    // // dir = opendir("/media/内容/" + std::string(username)).c_str());
    // dir = opendir("/media/");
    // if (dir == nullptr)
    // {
    //     std::cout << "无法打开目录" << std::endl;
    //     return false;
    // }

    //  uid_t uid = getuid();  // 获取当前进程的有效用户 ID

    // // struct passwd* pw = getpwuid(uid);
    // // std::string Username = pw->pw_name;
    // //     std::cout << "当前非 root 用户名：" << Username << std::endl;

    // while ((entry = readdir(dir)) != nullptr)
    // {
    //     if (entry->d_type == DT_DIR && std::string(entry->d_name) != "." && std::string(entry->d_name) != "..")
    //     {

    //         // usbPath = "/media/" + std::string(username) + "/" + std::string(entry->d_name);
    //         std::string usbname = std::string(entry->d_name);
    //         std::cout << "------------usbname是--------" << std::endl
    //                   << usbname << std::endl;

    //         std::string Username = std::string(username);
    //         std::cout << "------------Username是--------" << std::endl
    //                   << Username << std::endl;
                      
    //         if (usbname != Username && usbname != "root" )
    //         {
    //             /* code */
    //             usbPath = "/media/" + usbname;
    //             std::cout << "------------usb的路径是--------" << std::endl
    //                       << usbPath << std::endl;
    //             break;
    //         }
    //     }
    // }    
    // // sleep(2);
    // // string str(path.begin(), path.end());
    // // usbPath = str;
    // // std::cout << "------------usb的路径是--------" << std::endl
    // //           << usbPath << std::endl;

    // closedir(dir);
    // if (usbPath.empty())
    // {
    //     std::cout << "未找到插入的U盘\n";
    //     return false;
    // }

    // 要移动的文件路径列表
    std::vector<std::string> filePaths = {
        "sqldiff",
        "sqlite3",
        "sqlite3_analyzer"};
    std::string predbPath = usbPath + "/test.db";
    std::ifstream checkFile(predbPath);
    if (checkFile)
    {
        std::cout << "U盘中已存在test.db文件" << std::endl;
    }
    else
    {
        filePaths.push_back("test.db");
    }
    MoveFilesToUSB(filePaths, usbPath);
    std::cout << "sqlite初始化成功\n";
    return true;
}

// 判断u盘是否已进行初始化
bool AuditFun::IfInitializeSQL()
{
    std::string lastdbPath = usbPath + "/test.db";
    std::ifstream checkFile(lastdbPath);
    if (checkFile)
    {
        std::cout << "U盘已经初始化" << std::endl;
        return true;
    }
    else
    {
        std::cout << "U盘未初始化" << std::endl;
    }
    return false;
}

// 获取日志信息
string AuditFun::getIp()
{
    QString strIpAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // 获取第一个本主机的IPv4地址
    int nListSize = ipAddressesList.size();
    for (int i = 0; i < nListSize; ++i)
    {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
            ipAddressesList.at(i).toIPv4Address()) {
            strIpAddress = ipAddressesList.at(i).toString();
            break;
        }
    }
    // 如果没有找到，则以本地IP地址为IP
    if (strIpAddress.isEmpty())
        strIpAddress = QHostAddress(QHostAddress::LocalHost).toString();
    string ret = strIpAddress.toStdString();

    return ret;


}
string AuditFun::getMac()
{
    QList<QNetworkInterface> nets = QNetworkInterface::allInterfaces();// 获取所有网络接口列表
    int nCnt = nets.count();
    QString strMacAddr = "";
    for(int i = 0; i < nCnt; i ++)
    {
        // 如果此网络接口被激活并且正在运行并且不是回环地址，则就是我们需要找的Mac地址
        if(nets[i].flags().testFlag(QNetworkInterface::IsUp) && nets[i].flags().testFlag(QNetworkInterface::IsRunning) && !nets[i].flags().testFlag(QNetworkInterface::IsLoopBack))
        {
            strMacAddr = nets[i].hardwareAddress();
            break;
        }
    }
    string ret = strMacAddr.toStdString();

    return ret;
}
string AuditFun::getTime()
{
    time_t timep;
    time(&timep);
    char tmp[64];
    strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&timep));
    std::cout << "tmp:" << tmp << std::endl;
    return tmp;
}


string getUsbId(string usbPath)
{
    UsbIO usbIO(usbPath);
    unsigned char data[16]={0};
    usbIO.ReadPhysicalSector(35, 0, data, 16);
    string usbid;
    // 将每个字节转换为对应的ASCII字符
    for (const auto& byte : data) {
        usbid += static_cast<char>(byte);
    }

    std::cout << usbid << std::endl;
    return usbid;
}

// // sqlite插入原始的审计信息
// bool AuditFun::insertAuditInfo()
// {

//     sqlite3 *db;
//     char *zErrMsg = 0;
//     int rc;
//     const char *sql;

//     string macIp, insertionTime, computerIp, usbnumber, lastreadtime, lastwritetime, removaltime, installedsp, deptid, nickname, departmentname, areaname;
//     string readcount, writecount, areaid, userid;

//     insertionTime = this->getTime();
//     string usbid = getUsbId(usbPath);
//     qDebug() <<"2usbid=======" <<usbid;


//     usbnumber = "B000001";
//     readcount = "1";
//     writecount = "1";
//     lastreadtime = insertionTime;
//     lastwritetime = insertionTime;
//     areaid = "1";
//     userid = "1";
//     removaltime = insertionTime;
//     installedsp = "1";
//     deptid = "205";
//     nickname = "若依";
//     departmentname = "城阳";
//     areaname = "青岛单位";

//     macIp = this->getMac();

//     computerIp = this->getIp();

//     // open database
//     std::string dbPath = usbPath + "test.db";
//     std::cout << "*************the db path is*************" << dbPath << ::endl;
//     /* Open database */
//     rc = sqlite3_open(dbPath.c_str(), &db);

//     if (rc)
//     {
//         fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
//         exit(0);
//     }
//     else
//     {
//         //fprintf(stderr, "Opened database successfully\n");
//         std::cout << "Opened database successfully" << std::endl;
//     }
// // create sql statement
// std:
//     string sqlstatement = "insert into eu_usb_info (usb_number,readCount,writeCount,lastReadTime,lastWriteTime,area_id,user_id,insertionTime,removalTime,computerIp,installedSP,dept_id,macIp,nick_name,department_name,area_name) values('" + usbnumber + "','" + readcount + "','" + writecount + "','" + lastreadtime + "','" + lastwritetime + "','" + areaid + "','" + userid + "','" + insertionTime + "','" + removaltime + "','" + computerIp + "','" + installedsp + "','" + deptid + "','" + macIp + "','" + nickname + "','" + departmentname + "','" + areaname + "');";
//     sql = sqlstatement.c_str();

//     // execute sql statement
//     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
//     if (rc != SQLITE_OK)
//     {
//         //fprintf(stderr, "SQL error: %s\n", zErrMsg);
//         std::cout << "SQL error:" << zErrMsg << std::endl;
//         sqlite3_free(zErrMsg);
//     }
//     else
//     {
//         //fprintf(stdout, "Records created successfully\n");
//         std::cout << "Records created successfully\n" << std::endl;
//     }
//     sqlite3_close(db);
//     return 0;
// }

// sqlite插入u盘使用日志信息
// bool AuditFun::insertUseInfo(string File_name, string Operate_type, string Operate_time, string Usb_id)
// {
//     sqlite3 *db;
//     char *zErrMsg = 0;
//     int rc;
//     const char *sql;

//     string file_name = File_name;
//     string operate_type = Operate_type;
//     string operate_time = Operate_time;
//     string usb_id = Usb_id;
//     // open database
//     std::string dbPath = usbPath + "/test.db";
//     std::cout << "*************the db path is*****************" << dbPath << ::endl;
//     /* Open database */
//     rc = sqlite3_open(dbPath.c_str(), &db);
//     if (rc)
//     {
//         fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
//         exit(0);
//     }
//     else
//     {
//         fprintf(stderr, "Opened database successfully\n");
//     }
//     string sqlstatement = "insert into operate_log (file_name,operate_type,operate_time,usb_id) values ('" + file_name + "','" + operate_type + "','" + operate_time + "','" + usb_id + "');";
//     sql = sqlstatement.c_str();
//     // execute sql statement
//     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
//     if (rc != SQLITE_OK)
//     {
//         fprintf(stderr, "SQL error: %s\n", zErrMsg);
//         sqlite3_free(zErrMsg);
//     }
//     else
//     {
//         fprintf(stdout, "Records created successfully\n");
//     }
//     sqlite3_close(db);
//     return true;
// }

// 把审计信息发送给后端接口
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userip)
{
    size_t total_size = size * nmemb;
    printf("%s", (char *)contents);
    return total_size;
}
bool postUrl(const char *json)
{
    // CURL *curl;
    // CURLcode res;

    // curl = curl_easy_init();
    // if (curl)
    // {
    //     struct curl_slist *headers = NULL;
    //     headers = curl_slist_append(headers, "Content-Type: application/json");

    //     curl_easy_setopt(curl, CURLOPT_POST, 1L);

    //     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    //     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json);
    //     curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/system/usbInfo"); // 替换为您要发送请求的URL

    //     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);

    //     res = curl_easy_perform(curl);
    //     if (res != CURLE_OK)
    //     {
    //         fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    //         curl_easy_cleanup(curl);
    //         return false;
    //     }

    //     curl_easy_cleanup(curl);
    // }

    // return true;
}
int Callback(void *data, int argc, char **argv, char **azColName)
{
    char json[1024];

    std::string usbNumber = argv[1] ? std::string(argv[1]) : "";
    int readCount = argv[2] ? std::atoi(argv[2]) : 0;
    int writeCount = argv[3] ? std::atoi(argv[3]) : 0;
    std::string lastReadTime = argv[4] ? std::string(argv[4]) : "";
    std::string lastWriteTime = argv[5] ? std::string(argv[5]) : "";
    int areaId = argv[6] ? std::atoi(argv[6]) : 0;
    int userId = argv[7] ? std::atoi(argv[7]) : 0;
    std::string areaName = argv[16] ? std::string(argv[16]) : "";
    std::string insertionTime = argv[8] ? std::string(argv[8]) : "";
    std::string removalTime = argv[9] ? std::string(argv[9]) : "";
    std::string computerIp = argv[10] ? std::string(argv[10]) : "";
    std::string macIp = argv[13] ? std::string(argv[13]) : "";
    int installedSP = argv[11] ? std::atoi(argv[11]) : 0;
    int deptId = argv[12] ? std::atoi(argv[12]) : 0;
    std::string deptName = argv[14] ? std::string(argv[14]) : "";

    snprintf(json, sizeof(json),
             "{\"usbNumber\":\"%s\",\"readCount\":%d,\"writeCount\":%d,\"lastReadTime\":\"%s\",\"lastWriteTime\":\"%s\",\"areaId\":%d,\"userId\":%d,\"areaName\":\"%s\",\"insertionTime\":\"%s\",\"removalTime\":\"%s\",\"computerIp\":\"%s\",\"macIp\":\"%s\",\"installedSP\":%d,\"deptId\":%d,\"deptName\":\"%s\"}",
             usbNumber.c_str(), readCount, writeCount, lastReadTime.c_str(), lastWriteTime.c_str(), areaId, userId, areaName.c_str(), insertionTime.c_str(), removalTime.c_str(), computerIp.c_str(), macIp.c_str(), installedSP, deptId, deptName.c_str());

    std::cout << "挂载的JSON" << json << endl;
    if (postUrl(json))
    {
        printf("JSON: %s\n", json);
        printf("POST request sent successfully.\n");
    }
    else
    {
        printf("Failed to send POST request.\n");
    }

    return 0;
}
// bool AuditFun::PostAuditInfo()
// {
//     sqlite3 *db;
//     char *zErrMsg = 0;
//     char *err_msg = 0;
//     std::string dbPath = usbPath + "/test.db";
//     int rc = sqlite3_open(dbPath.c_str(), &db); // 替换为您的数据库文件名
//     if (rc != SQLITE_OK)
//     {
//         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
//         sqlite3_close(db);
//         return false;
//     }
//     const char *sql = "SELECT * FROM eu_usb_info"; // 替换为您的表名
//     rc = sqlite3_exec(db, sql, Callback, 0, &err_msg);
//     if (rc != SQLITE_OK)
//     {
//         fprintf(stderr, "SQL error: %s\n", err_msg);
//         sqlite3_free(err_msg);
//         sqlite3_close(db);
//         return false;
//     }
//     sqlite3_close(db);
//     return true;
// }

bool AuditFun::PostRegistInfo(string name, string worknum, int level, string user_number, string ip, string mac)
{
    // CURL *curl;
    // CURLcode res;

    // curl = curl_easy_init();
    // if (curl)
    // {
    //     struct curl_slist *headers = NULL;
    //     headers = curl_slist_append(headers, "Content-Type:application/json");
    //     curl_easy_setopt(curl, CURLOPT_POST, 1L);
    //     char json[1024];

    //     string usbNumber = user_number;
    //     string userName = name;
    //     int userId = atoi(worknum.c_str());
    //     string computerIp = ip;
    //     string macIp = mac;
    //     int roleId = level;

    //     snprintf(json, sizeof(json),
    //              "{\"usbNumber\":\"%s\",\"userId\":%d,\"userName\":\"%s\",\"computerIp\":\"%s\",\"macIp\":\"%s\",\"roleId\":%d}",
    //              usbNumber.c_str(), userId, userName.c_str(), computerIp.c_str(), macIp.c_str(), roleId);
    //     std::cout << json << endl;
    //     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    //     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json);                             // 指定post内容
    //     curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/system/usbInfo"); // 指定url

    //     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    //     res = curl_easy_perform(curl);
    //     if (res != CURLE_OK)
    //     {

    //         fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    //     }
    //     curl_easy_cleanup(curl);
    // }

    // return true;
}

// void AuditFun::zipFolder(zipFile zip, const char *folder_path, const char *password)
// {
//     DIR *dir;
//     struct dirent *entry;

//     // 打开文件夹
//     dir = opendir(folder_path);
//     if (!dir)
//     {
//         printf("无法打开文件夹：%s\n", folder_path);
//         return;
//     }
//     cout << "========================"<<endl;
//     // 遍历文件夹中的文件和子文件夹
//     while ((entry = readdir(dir)) != NULL)
//     {
//         const char *name = entry->d_name;
//         char file_path[MAX_PATH];

//         // 构建文件的完整路径
//         snprintf(file_path, sizeof(file_path), "%s/%s", folder_path, name);

//         // 忽略 "." 和 ".."
//         if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
//         {
//             continue;
//         }

//         // 检查文件的类型
//         if (entry->d_type == DT_DIR)
//         {
//             // 如果是子文件夹，则递归压缩子文件夹 压缩
//             char subfolder_path[MAX_PATH];
//             snprintf(subfolder_path, sizeof(subfolder_path), "%s", name);

//             zipFolder(zip, file_path, password);
//         }
//         else
//         {
//             // 如果是文件，则将其添加到 ZIP 文件中
//             char entry_name[MAX_PATH];
//             snprintf(entry_name, sizeof(entry_name), "%s", name);

//             FILE *file = fopen(file_path, "rb");
//             if (file)
//             {
//                 // 将文件添加到 ZIP 文件中，并使用密码进行加密
                
//                 zipOpenNewFileInZip3_64(zip, entry_name, nullptr, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, 0,0);
//                 char buffer[8192];
//                 int bytesRead;
//                 while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0)
//                 {
//                     zipWriteInFileInZip(zip, buffer, bytesRead);
//                 }
//                 zipCloseFileInZip(zip);
//                 fclose(file);
//             }
//             else
//             {
//                 printf("无法打开文件：%s\n", file_path);
//             }
//         }
//     }

//     closedir(dir);
// }

// void AuditFun::add_directory_to_zip(const char *zip_name, const char *password, const char *folder_path)
// {
//     zipFile zip = zipOpen(zip_name, APPEND_STATUS_CREATE);
//     if (zip == NULL)
//     {
//         printf("无法打开ZIP文件\n");
//         return;
//     }
//     zipFolder(zip, folder_path,password);

//     zipClose(zip,nullptr);

//     std::cout << "this is add_directory_to_zip" << std::endl;
// }
